# Copyright 2009-2016 BitMover, Inc

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

#     http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# There are two main things being tested: BAM and Fast-Pull
# BAM was introduced in 4.1, but we are using a BAM baseline as 4.2
#
# 4.3 introduced Fast Pull which includes a whole sfile under some
# circumstances.

OLDVER=4.2
OLDBK=/build/bitkeeper-$OLDVER

# use new parallel clone in tests
_BK_FSTYPE=nfs
export _BK_FSTYPE

echo $N Check bitkeeper 4.2 installation ............................$NL
if [ -n "$BK_DEV_SKIPTEST" ]; then echo skipped; exit 0; fi
# Skip this test for Windows VISTA
OSTYPE=`uname -s`
case $OSTYPE in
	MINGW32_NT-6.*) echo skipped; exit 0;;
esac
# http://config.bitmover.com:7777/cgi-bin/view.cgi?id=2016-05-02-002
BKL_PRO=BKL65908cc51572709000001200fffff000000000
BKL_P1=YgAAAo4AAAADgQAAAAHZK6YXrWpbvvL7wuT1Fj8Z4gsjm633vW6T8Irespi/d1GL
BKL_P2=LltIV1NobkMykn2BWS45ph8r+VpBbslq4r8cOffc7UK3qd40y6uFW+ud1mMUJjYm
BKL_P3=Jl+mK0yL7V9E8uvsWU8VF6Wr/0lFDLZOMAbLUeTnh3EM8WcTqE0oar00Wygc0A==

echo license: $BKL_PRO > c
echo licsign1: $BKL_P1 >> c
echo licsign2: $BKL_P2 >> c
echo licsign3: $BKL_P3 >> c
mv c "`bk dotbk`"/config
test -d $OLDBK || {
    # Skip this test if we don't have at least 5gigs free
    df -Pk /build 2>/dev/null |
        perl -e '$_ = <>; $_ = <>; exit 0 if /^\S+\s+\d+\s+\d+\s+(\d+)\s+\d+%/ && $1 > 5e6; exit 1' || {
	echo skipped
	exit 0
    }
    bk upgrade $Q -f -d $BK_TCOMPAT_ARCH \
	    http://downloads.bitkeeper.com/unsupported/bk-$OLDVER >out 2>ERR || {
	    grep -q "No upgrade for the arch.*found" ERR && {
	        # can use $BK_TCOMPAT_ARCH to fix if your platform
		# isn't one of the official
		echo skipped
		exit 0
	    }
	    echo image fetch failed
	    exit 1
    }
    # NOTE bk-3.2.x didn't set exit status...
    echo y | BK_NOLINKS=1 ./bk-$OLDVER-* $OLDBK >out 2>err || fail
    rm -f $OLDBK/config

    # generate a crypto key for tests
    $OLDBK/bk crypto -i 1024 $OLDBK/my.sec $OLDBK/my.pub || fail
}
VER=`$OLDBK/bk version -s`
test X$VER = X$OLDVER || {
	echo bk not installed correctly
	exit 1
}
$OLDBK/bk _eula -a
echo OK

mkBINs

echo -------------- crypto tests
echo $N New and old version should generate the same signature ......$NL
$OLDBK/bk crypto -s $OLDBK/my.sec < "$BIN2" > sig1 || fail
bk crypto -s $OLDBK/my.sec < "$BIN2" > sig2 || fail
echo OK

echo $N New and old versions should validate signature ..............$NL
$OLDBK/bk crypto -v $OLDBK/my.pub sig1 < "$BIN2" || fail
bk crypto -v $OLDBK/my.pub sig1 < "$BIN2" || fail
$OLDBK/bk crypto -v $OLDBK/my.pub sig2 < $BIN2 || fail
bk crypto -v $OLDBK/my.pub sig2 < "$BIN2" || fail
echo OK

echo $N Old version encrypts and new version decrypts ...............$NL
$OLDBK/bk crypto -e $OLDBK/my.pub < "$BIN2" > enc || fail
bk crypto -d $OLDBK/my.sec < enc > out || fail
cmp -s "$BIN2" out || fail
rm -f enc out
echo OK

echo $N New version encrypts and old version decrypts ...............$NL
bk crypto -e $OLDBK/my.pub < "$BIN2" > enc || fail
$OLDBK/bk crypto -d $OLDBK/my.sec < enc > out || fail
cmp -s "$BIN2" out || fail
rm -f enc out
echo OK

KEY=64338d0365e3c7da
echo $N New and old versions should symetric encrypt to same data ...$NL
$OLDBK/bk crypto -E $KEY < "$BIN2" > enc1 || fail
bk crypto -E $KEY < "$BIN2" > enc2 || fail
cmp -s enc1 enc2 || fail
rm -f enc2
echo OK

echo $N Both versions should be able to decrypt data ................$NL
$OLDBK/bk crypto -D $KEY < enc1 > out || fail
cmp -s "$BIN2" out || fail
bk crypto -D $KEY < enc1 > out || fail
cmp -s "$BIN2" out || fail
rm -f enc1 out
echo OK

echo $N Check hashing with new and old versions .....................$NL
$OLDBK/bk crypto -h - < "$BIN2" > hash1
bk crypto -h - < "$BIN2" > hash2 || fail
cmpfiles hash1 hash2
echo OK

echo $N Check hmacs with new and old versions .......................$NL
$OLDBK/bk crypto -h - key < "$BIN2" > hash1
bk crypto -h - key < "$BIN2" > hash2 || fail
cmpfiles hash1 hash2
echo OK

echo -------------- gone file automerge tests
echo $N Test auto-merge on gone files works with new del format .....$NL
fresh_commercial --compat project
bk clone $Q --sccs-compat . ../copy
bk edit $Q BitKeeper/etc/gone
echo "a@b.c|d|20001010101010|63920|1fea66be52324149" >> BitKeeper/etc/gone
bk delta $Q -yfakegone BitKeeper/etc/gone
bk commit $Q -yfakegone
cd ../copy
GONENAME="`bk log -r1.0 -nd:RM_NAME: BitKeeper/etc/gone`"
$OLDBK/bk rm -f BitKeeper/etc/gone
bk commit $Q -yfakenewgone
echo "a@b.c|d|20000101010101|63320|1fea36b352324149" > BitKeeper/etc/gone
bk new $Q BitKeeper/etc/gone
bk commit $Q -yfakenewgone
cd ../project
bk pull $Q ../copy
test "`bk cat BitKeeper/etc/gone | wc -l`" -eq 3 || fail
echo OK

echo $N Test auto-merge on gone files uses existing deleted name ....$NL
cd ../copy
$OLDBK/bk rm -f BitKeeper/etc/gone
bk sfiles | grep '~.$' > ERR && fail -f ERR
bk commit $Q -ygone
cd ../project
bk rm -f BitKeeper/etc/gone
bk sfiles | grep '~.$' > ERR && fail -f ERR
bk commit $Q -ygone
bk pull $Q ../copy
bk sfiles | grep '~.$' > ERR && fail -f ERR
echo OK

echo $N Test delete of delete either renaming or doing nop ..........$NL
cd ../copy
touch foo
bk new $Q foo
RMNAME="`bk log -r1.0 -nd:RM_NAME: foo`"
bk rm foo
OLDGONENAME=`bk sfiles -g BitKeeper/deleted | grep gone~`
NRMNAME=`bk prs -r1.0 -hnd:RM_NAME: $OLDGONENAME`
bk sfiles -g BitKeeper/deleted | bk _sort > GOT
cat <<EOF | bk _sort > WANT
BitKeeper/deleted/.del-gone
$OLDGONENAME
$RMNAME
EOF
cmpfiles WANT GOT
# layout in new deleted anything that is not already there
bk -rBitKeeper/deleted rm -f
# check it out
bk sfiles -g BitKeeper/deleted | bk _sort > GOT
cat <<EOF | bk _sort > WANT
$RMNAME
$NRMNAME
$GONENAME
EOF
cmpfiles WANT GOT
cd ..
echo OK

echo -------------- fast pull tests
echo $N Set up a patch new, BAM and many deltas .....................$NL
rm -fr project copy
# don't do "FOO=1 shell-function" but break out env setting and clearing
# use uncached form of commercial since env is different
_BK_BAM_V2=1
export _BK_BAM_V2
_commercial_config > c
echo compression:none >> c
bk setup -a -f --sccs-compat -cc project.noremap || fail
cd project.noremap
echo BAMBAM > BAM
bk new $Q -b BAM || fail
bk commit $Q -ybamdata
test -d SCCS || fail
test -f BitKeeper/BAM/index.db || fail
cd ..
bk clone $Q project.noremap copy.noremap || fail
unset _BK_BAM_V2
bk clone --hide-sccs-dirs $Q project.noremap project
bk clone $Q project copy
cd copy.noremap
bk parent $Q ../project
cd ../project
# verify new style BAM and BLOB
test -d SCCS && fail
test -d BitKeeper/BAM -a ! -f BitKeeper/BAM/index.db || fail
touch send-as-sfile send-as-deltas
bk new $Q send-as-sfile send-as-deltas || fail
bk commit $Q --tag=BASE -yfooze || fail
bk push $Q ../copy
bk push $Q ../copy.noremap
touch newfile
bk new $Q newfile || fail
bk edit $Q send-as-sfile send-as-deltas || fail
# 9 is the internal baseline for largest that passes as a patch
for i in 1 2 3 4 5 6 7 8 9; do
	bk delta $Q -l -f -ymkdeltas send-as-deltas send-as-sfile || fail
done
# adding a 10th to send-as-sfile means it will move as an sfile
bk delta $Q -l -f -ysend-as-sfile send-as-sfile || fail
bk unedit $Q send-as-sfile send-as-deltas || fail
bk commit $Q -y'deltas to existing files' || fail
bk push $Q ../project.noremap || fail
#
bk makepatch $Q -B -r+ > ../PATCH || fail
bk makepatch $Q -B -C -r+ > ../PATCH-COMPAT || fail
bk send $Q -r+ - > ../SEND || fail
cd "$HERE"
mv project project.remap
mv project.noremap project
cd project
$OLDBK/bk makepatch $Q -B -r+ > ../OLDPATCH || fail
$OLDBK/bk send $Q -r+ - > ../OLDSEND || fail
cd ..
#cmpfiles SEND OLDSEND
#cmpfiles PATCH-COMPAT OLDPATCH
#cmp -s PATCH OLDPATCH && fail
tar cf copy.tar copy
tar cf copy.noremap.tar copy.noremap
cd "$HERE"
mv project project.noremap
mv project.remap project
echo OK

echo $N Start new and old bkds ......................................$NL
cd "$HERE"
OLDP=`port 54500`
# old bkd will have "No root for triggers!" ttyprintf
BK_TTYPRINTF= $OLDBK/bk bkd -d -p$OLDP -ikill 2> OLDERR || fail -f OLDERR
bk bkd -d -aPORT -ikill 2> NEWERR || fail -f NEWERR
NEWP=`cat PORT`
trap "bk _kill bk://localhost:$OLDP; bk _kill bk://localhost:$NEWP" 0
echo OK

echo $N Demo clone --parents error message ..........................$NL
bk clone --parents bk://localhost:$OLDP/copy.noremap parents > GOT 2>&1
grep -q 'The remote BitKeeper binary is missing a feature that the local' GOT ||
    fail
echo OK

echo $N Push old server new client \(FAIL\) ...........................$NL
cd project || fail
bk push $Q bk://localhost:$OLDP/copy.noremap 2>ERR && fail -f ERR
bk getmsg -= bkd_missing_feature fastpatch > WANT
cmpfiles ERR WANT
echo OK

echo $N Push new server old client \(FAIL\)............................$NL
cd ..
rm -fr copy
tar xf copy.tar
cd project.noremap || fail
$OLDBK/bk push $Q bk://localhost:$NEWP/copy 2>ERR && fail -f ERR
cat << EOF > WANT
=================================  Error   =================================
The error code returned from BitKeeper was:
	bk_missing_feature fastpatch
Please send mail to support@bitmover.com to request assistance.
============================================================================
EOF
cmpfiles ERR WANT
echo OK

echo $N Pull old server new client \(FAIL\)............................$NL
cd ..
rm -fr copy
tar xf copy.tar
cd copy || fail
bk pull $Q bk://localhost:$OLDP/project.noremap 2>ERR && fail -f ERR
bk getmsg -= bkd_missing_feature fastpatch > WANT
cmpfiles ERR WANT
echo OK

echo $N Pull new server old client \(FAIL\)............................$NL
cd ..
rm -fr copy.noremap
tar xf copy.noremap.tar
cd copy.noremap || fail
$OLDBK/bk pull $Q bk://localhost:$NEWP/project 2>ERR && fail -f ERR
cat << EOF > WANT
=================================  Error   =================================
The error code returned from BitKeeper was:
	bk_missing_feature fastpatch
Please send mail to support@bitmover.com to request assistance.
============================================================================
EOF
cmpfiles ERR WANT
echo OK

echo $N Nested detached repo running behind old bkd .................$NL
cd "$HERE"
fresh_nested --compat nest
bk detach $Q --sccs-compat gcc ../newgcc || fail
cd ../newgcc
bk clone $Q . bk://localhost:$OLDP/oldgcc 2> ERR && fail -f ERR
grep -q "The current repository has a feature" ERR || fail -f ERR
echo OK

echo $N Nested detached repo running behind new bkd with old client .$NL
# even with feature mangled ChangeSet file, clone works.
$OLDBK/bk clone $Q . bk://localhost:$NEWP/newgcc2 || fail
# XXX put back more tests
echo OK

echo $N Old-bk clone of component behind nested-aware bkd fails .....$NL
cd "$HERE"
bk clone $Q bk://localhost:$OLDP/nest/gcc 2> ERR && fail
grep -q "good error msg" ERR || echo "failed (bug -- need good err msg)"

echo $N New clone -@ with old bkd fails gracefully ..................$NL
bk clone $Q -@project bk://localhost:$OLDP/blart >ERR 2>&1 && \
	fail -f ERR should have failed
grep -q "Repository doesn't exist" ERR || fail -f ERR wrong message
bk clone $Q -@project bk://localhost:$OLDP/copy >ERR 2>&1 && \
	fail -f ERR should have failed
grep -q "copy needs to be upgraded" ERR || fail -f ERR wrong message
echo OK

echo $N New clonemod with old bkd fails gracefully ..................$NL
bk clonemod $Q bk://localhost:$OLDP/blart project blart >ERR 2>&1 && \
	fail -f ERR should have failed
grep -q "Repository doesn't exist" ERR || fail -f ERR wrong message
bk clonemod $Q bk://localhost:$OLDP/copy project copy >ERR 2>&1 && \
	fail -f ERR should have failed
grep -q "copy needs to be upgraded" ERR || fail -f ERR wrong message
echo OK

echo -------------- sortkey repo interacting with old bk
echo $N Make a repo with illegal key order and test .................$NL
# From t.sortkeys, modified to be a csetprune instead of partition
BK_RANDOM=1000197497459702
BK_DATE_TIME_ZONE="98/09/22 16:23:31+00:00"
_BK_NO_UNIQ=1
export BK_DATE_TIME_ZONE _BK_NO_UNIQ BK_RANDOM
# do not use cache, as we want predictable repo
fresh_commercial --compat base
# two files, one 'del' will get move to a subdir, then pruned.
echo line > keep
touch del
bk new $Q keep del
bk commit $Q -ybase
bk clone $Q --sccs-compat . ../diamond
# make a diamon cset graph - here's the trunk - edit both
bk edit $Q keep del
echo foo > del
cat > keep <<EOF
1
line
EOF
# this is branch on del, because of path sorting
bk delta $Q -ytrunk keep del
bk commit $Q -ytrunk
# ... here's the branch - move del to component anno (anno sorts before del)
cd ../diamond
bk edit $Q keep
echo data >> keep
bk delta $Q -ybranch keep
bk commit $Q -ybranch
# make the merge
bk pull $Q
$OLDBK/bk clone $Q . ../diamond-old
$OLDBK/bk clone $Q . ../diamond-new4
bk prs -r+ -hnd:ROOTKEY: del > ../PRUNELIST
bk csetprune $Q -k1234567890abcdef < ../PRUNELIST
cd ../diamond-old
$OLDBK/bk csetprune $Q -S -k1234567890abcdef 2> NOISE < ../PRUNELIST 
bk check ChangeSet 2> GOT && fail
cat > WANT <<EOF
SCCS/s.ChangeSet: 1.3 is not earlier than 1.2.1.1
SCCS/s.ChangeSet: 1.3 is not earlier than 1.2.1.1
EOF
cmpfiles WANT GOT
# clean up for diff in next test
rm WANT GOT NOISE SCCS/b.ChangeSet
# run bk5 in bk4 mode and it should fail just like bk4
cd ../diamond-new4
bk csetprune $Q --bk4 -k1234567890abcdef 2> GOT < ../PRUNELIST && fail -f GOT
cat > WANT <<EOF
SCCS/s.ChangeSet: 1.3 is not earlier than 1.2.1.1
SCCS/s.ChangeSet: 1.3 is not earlier than 1.2.1.1
csetprune: failed
EOF
cmpfiles WANT GOT
# clean up for diff in next test
rm WANT GOT
echo OK

echo $N Show that csetprune --bk4 is same as bk4 csetprune ..........$NL
cd ..
bk --cd=diamond-old -r admin -Znone
bk --cd=diamond-new4 -r admin -Znone
diff -xBitKeeper -qr diamond-old diamond-new4 || fail
echo OK

echo $N Show that an writing erases meta data .......................$NL
cd diamond
bk check ChangeSet || fail

# show old bk can't read repo
$OLDBK/bk changes 2>ERR && fail -f ERR
grep -q bk-filever-5 ERR || fail
echo OK
